//
// Created by wxd on 2025/9/4.
// 定义引擎全局的类型转换器

#pragma once

#ifndef TYPE_CAST_H
#define TYPE_CAST_H

#pragma once

#include <memory>
#include <typeindex>
#include <unordered_map>
#include <mutex>
#include <functional>
#include <optional>
#include <string>

// 类型转换异常
class TypeCastException : public std::exception {
private:
    std::string message_;

public:
    explicit TypeCastException(const std::string& message)
        : message_("TypeCastException: " + message) {}

    const char* what() const noexcept override {
        return message_.c_str();
    }
};

// 全局类型转换器
class GlobalTypeCaster {
private:
    // 单例实例
    static GlobalTypeCaster* instance_;
    static std::mutex instanceMutex_;

    // 转换缓存：源类型 -> 目标类型 -> 转换函数
    std::unordered_map<
        std::type_index,
        std::unordered_map<
            std::type_index,
            std::function<void*(void*)>
        >
    > conversionRegistry_;

    // 类型检查缓存：对象地址 -> 类型信息
    std::unordered_map<const void*, std::type_index> typeCheckCache_;

    // 线程安全
    mutable std::mutex registryMutex_;
    mutable std::mutex cacheMutex_;

    // 私有构造函数（单例模式）
    GlobalTypeCaster() = default;

public:
    // 删除拷贝构造函数和赋值运算符
    GlobalTypeCaster(const GlobalTypeCaster&) = delete;
    GlobalTypeCaster& operator=(const GlobalTypeCaster&) = delete;

    // 获取单例实例
    static GlobalTypeCaster& getInstance() {
        std::lock_guard<std::mutex> lock(instanceMutex_);
        if (instance_ == nullptr) {
            instance_ = new GlobalTypeCaster();
        }
        return *instance_;
    }

    // 注册类型转换器
    template<typename Source, typename Target>
    void registerConverter(std::function<Target*(Source*)> converter) {
        std::lock_guard<std::mutex> lock(registryMutex_);

        const auto sourceType = typeid(Source);
        const auto targetType = typeid(Target);

        conversionRegistry_[sourceType][targetType] =
            [converter](void* sourcePtr) -> void* {
                return converter(static_cast<Source*>(sourcePtr));
            };
    }

    // 基本类型转换（带缓存）
    template<typename Target, typename Source>
    Target* cast(Source* source) {
        if (source == nullptr) return nullptr;

        // 检查缓存
        if (auto cachedResult = getCachedCast<Target>(source)) {
            return cachedResult;
        }

        // 执行转换
        Target* result = performCast<Target>(source);

        // 更新缓存
        updateCastCache(source, result);

        return result;
    }

    // 智能指针版本
    template<typename Target, typename Source>
    std::shared_ptr<Target> cast(const std::shared_ptr<Source>& source) {
        if (!source) return nullptr;

        Target* rawResult = cast<Target>(source.get());
        if (rawResult) {
            return std::shared_ptr<Target>(source, rawResult);
        }
        return nullptr;
    }

    // 安全转换（不抛出异常）
    template<typename Target, typename Source>
    std::optional<Target*> safeCast(Source* source) {
        try {
            return cast<Target>(source);
        } catch (const TypeCastException&) {
            return std::nullopt;
        }
    }

    // 类型检查
    template<typename Target, typename Source>
    bool isType(Source* source) {
        return safeCast<Target>(source).has_value();
    }

    // 清空缓存
    void clearCache() {
        std::lock_guard<std::mutex> lock(cacheMutex_);
        typeCheckCache_.clear();
    }

    // 清空指定对象的缓存
    void clearCacheForObject(const void* object) {
        std::lock_guard<std::mutex> lock(cacheMutex_);
        typeCheckCache_.erase(object);
    }

    // 获取缓存统计信息
    size_t getCacheSize() const {
        std::lock_guard<std::mutex> lock(cacheMutex_);
        return typeCheckCache_.size();
    }

private:
    // 获取缓存的转换结果
    template<typename Target, typename Source>
    Target* getCachedCast(Source* source) {
        std::lock_guard<std::mutex> lock(cacheMutex_);

        auto cacheIt = typeCheckCache_.find(source);
        if (cacheIt != typeCheckCache_.end()) {
            if (cacheIt->second == typeid(Target)) {
                return static_cast<Target*>(source);
            }
        }
        return nullptr;
    }

    // 更新转换缓存
    template<typename Source, typename Target>
    void updateCastCache(Source* source, Target* result) {
        std::lock_guard<std::mutex> lock(cacheMutex_);

        if (result != nullptr) {
            typeCheckCache_[source] = typeid(Target);
        } else {
            typeCheckCache_[source] = typeid(*source);
        }
    }

    // 执行实际的类型转换
    template<typename Target, typename Source>
    Target* performCast(Source* source) {
        const auto sourceType = typeid(*source);
        const auto targetType = typeid(Target);

        // 检查是否相同类型
        if (sourceType == targetType) {
            return static_cast<Target*>(source);
        }

        // 检查注册的转换器
        std::lock_guard<std::mutex> lock(registryMutex_);

        auto sourceIt = conversionRegistry_.find(sourceType);
        if (sourceIt != conversionRegistry_.end()) {
            auto targetIt = sourceIt->second.find(targetType);
            if (targetIt != sourceIt->second.end()) {
                void* result = targetIt->second(source);
                return static_cast<Target*>(result);
            }
        }

        // 尝试 dynamic_cast
        Target* result = dynamic_cast<Target*>(source);
        if (result != nullptr) {
            return result;
        }

        throw TypeCastException(
            "Cannot convert from " + std::string(sourceType.name()) +
            " to " + std::string(targetType.name())
        );
    }
};

// 静态成员初始化
GlobalTypeCaster* GlobalTypeCaster::instance_ = nullptr;
std::mutex GlobalTypeCaster::instanceMutex_;

#endif //TYPE_CAST_H
